#include "ADD.h"
#include "Joueur.h"
//#include "ConfigurerNiveaux.h"

#include "MetaRace.h"
#include "MetaClasse.h"

//#include "lib.h"

using namespace std;
using namespace boost::assign;

int main(int argc, char* argv[])
  /*
   * retourne 0 si exécution OK
   * retourne 1 si problème
   * retourne 2 si aide affichée
   */
{
  //lireNiveauxSortie();

  blank() << setfill('#') << setw(80) << '#' << endl << setfill(' ')
	  << '#' << setw(47) << "- NouveauJoueur -" << setw(32) << '#'
	  << endl << '#' << setw(79) << '#' << endl
	  << '#' << setw(56) << "Création d'un nouveau personnage"
	  << setw(24) << '#' << endl
	  << '#' << setw(44) << "Projet ADD" << setw(35) << '#' << endl
	  << '#' << setw(79) << '#' << endl
	  << '#' << setw(58) << "Développé par Johan \"Solo\" Luisier"
	  << setw(23) << '#' << endl
	  << '#' << setw(41) << "2007" << setw(38) << '#'
	  << endl << setfill('#') << setw(80) << '#' << endl << endreq;

  unsigned int i;
  string help("-h");

  if (argc == 1)
    {
      error() << "Essayer ./NouveauJoueur -h" << endreq;
      return 1;
    }

  for(i = 0; i < static_cast<unsigned int>(argc); i++)
    {
      if (argv[i] == help)
	{
	  blank() << "Utilisation ./NouveauJoueur Nom code_race code_classe"
		  << endl << "code_race :" << endl << setfill(' ')
		  << setw(6) << "1 =>" << setw(12) << "Humain"     << endl
		  << setw(6) << "2 =>" << setw(12) << "Nain"       << endl
		  << setw(6) << "3 =>" << setw(12) << "Elfe"       << endl
		  << setw(6) << "4 =>" << setw(12) << "Gnome"      << endl
		  << setw(6) << "5 =>" << setw(12) << "Hobbit"     << endl
		  << setw(6) << "6 =>" << setw(12) << "Demi-Elfe"  << endl
		  << setw(6) << "7 =>" << setw(12) << "Demi-orque" << endl
		  << setw(6) << "8 =>" << setw(12) << "Demi-Ogre"  << endl
		  << "code_classe :" << endl
		  << setw(6) << "1 =>" << setw(12) << "Guerrier"    << endl
		  << setw(6) << "2 =>" << setw(12) << "Paladin"     << endl
		  << setw(6) << "3 =>" << setw(13) << "Rôdeur"      << endl
		  << setw(6) << "4 =>" << setw(12) << "Voleur"      << endl
		  << setw(6) << "5 =>" << setw(12) << "Barde"       << endl
		  << setw(6) << "6 =>" << setw(13) << "Prêtre"      << endl
		  << setw(6) << "7 =>" << setw(12) << "Druide"      << endl
		  << setw(6) << "8 =>" << setw(12) << "Magicien"    << endl
		  << setw(6) << "9 =>" << setw(13) << "Spécialiste" << endreq;    
		      
	  return 0;
	}
    }
  vector<string> args;
  
  debug() << "Nbr arg av gérer_blancs " << argc << endreq;
  gererEspacesBlancs(argv, argc, args);
  debug() << "Nbr arg ap gérer_blancs " << argc << endreq;

  for(unsigned int i(0); i < static_cast<unsigned int>(argc); i++)
    debug() << "Contrôle : args[" << i << "] = " << args[i] << endreq;    
  
  if (argc < 4)
    {
      error() << "Utilisation  ./NouveauJoueur Nom code_race code_classe"
		<< endreq;
      error() << "Essayer avec l'option -h pour l'aide" << endreq;
      return 1;
    }

  string traits[6] = {"Force", "Dextérité", "Constitution",
		      "Intelligence", "Sagesse", "Charisme"};
  string question;

  unsigned int x(0), tmp;
  vector< unsigned int > tab( 7, 0 );

  blank() << "Entrer vos traits bruts, les ajustements de races sont "
	  << "appliqués" << endl << "automatiquement après." << endreq;

  for(i = 0; i < 6; i++)
    {
      question = traits[i] + " : ";
      tmp = demanderUnsignedBorne(question, 1, 19);
      tab[i] = tmp;
    }

  Race* gars;

  debug() << 1 << args[1] << " - " << args[2] << " - " << args[3] << endreq;

  string nom(args[1]);
  
  debug() << 2 << args[1] << " - " << args[2] << " - " << args[3] << endreq;

  string race;
 
  string truc(args[2]);

  debug() << 3 << args[1] << " - " << args[2] << " - " << args[3] << endreq;

  unsigned int quoi;
  if ( ! lireString( truc.substr( 0, 1 ), quoi ) )
    {
      error() << "Code race illisible!" << endreq;
      exit( 1 );
    }
  vector< string > races = list_of( "Humain" )( "Nain" )( "Elfe" )
    ( "Gnome" )( "Hobbit" )( "Demi-Elfe" )( "Demi-Orque" )( "Demi-Ogre" );

  if ( quoi > races.size() )
    {
      error() << "Code race inconnu : " << quoi << endreq;
      exit( 1 );
    }

  MetaRace modeleRace( races[ quoi ] );
  // char quoi(truc[0]);
  // switch (quoi)
  //   {
  //   case '1':
  //     gars = new Humain(x);
  //     race = "Humain";
  //     break;
  //   case '2':
  //     gars= new Nain(x);
  //     race = "Nain";
  //     break;
  //   case '3':
  //     gars = new Elfe(x);
  //     race = "Elfe";
  //     break;
  //   case '4':
  //     gars = new Gnome(x);
  //     race = "Gnome";
  //     break;
  //   case '5':
  //     gars = new Hobbit(x);
  //     race = "Hobbit";
  //     break;
  //   case '6':
  //     gars = new DemiElfe(x);
  //     race = "Demi-Elfe";
  //     break;
  //   case '7':
  //     gars = new DemiOrque(x);
  //     race = "Demi-Orque";
  //     break;
  //   case '8':
  //     gars = new DemiOgre(x);
  //     race = "Demi-Ogre";
  //     break;
  //   default:
  //     error() << truc << endreq;
  //     error() << "race inconnue" << endreq;
  //     exit(1);
  // }

  gars = modeleRace.creerObjet();

  StatusCode sc( gars -> rempliPrerequis( tab ) );

  if ( !sc )
    {
      error() << sc.message() << " (" << sc.code()
	      << " est la limite et la valeur est " << tab[ sc.valeur() ]
	      << ")" << endreq;
      return 0;
    }

  if (tab[0] == 18)
    {
      tmp = demanderUnsignedBorne("Entrer le score de force exceptionnelle : ", 0, 100);
      tab[6] = tmp;
    }
  else
    tab[6] = 0;

  debug() << "Race OK" << endreq;

  vector<Classe*> war;
  Joueur *bob;
  bob = 0;

  for(i = 3; i < static_cast<unsigned int>(argc); i++)
    {
      truc = args[i];
      quoi = truc[0];
      switch(quoi)
	{
	case '1':
	  war.push_back(new Guerrier(1, tab, x, race));
	  break;
	case '2':
	  war.push_back(new Paladin(1, tab, x, race));
	  break;
	case '3':
	  war.push_back(new Rodeur(1, tab, x, race));
	  break;
	case '4':
	  war.push_back(new Voleur(1, tab, x, race));
	  break;
	case '5':
	  war.push_back(new Barde(1, tab, x, race));
	  break;
	case '6':
	  war.push_back(new Clerc(1, tab, x, race));
	  break;
	case '7':
	  war.push_back(new Druide(1, tab, x, race));
	  break;
	case '8':
	  war.push_back(new Mage(1, tab, x, race));
	  break;
	case '9':
	  war.push_back(new Spec(1, tab, x, race));
	  break;
	default:
	  error() << "Classe inconnue" << endreq;
	  return 1;
	}
      
      debug() << "Classe OK" << endreq;

      war.back() -> appliquerModif();

      if (i == 3)
	bob = new Joueur(war.back(), gars, nom);
      else
	bob -> ajoutClasse(war.back());
    }

  tmp = demanderUnsigned("Entrer le nombre de PV : ");

  bob -> setPV(tmp);

  debug() << "Joueur OK" << endreq;

  func() << "PPs restants : " << x << endreq;

  bob -> setPP(x);
  
  //bob -> info();

  bob -> determinerDonsDesavantages(Desav);
  bob -> determinerDonsDesavantages(Don);  
  bob -> determinerCompetences();
  bob -> augmenterCompetences();

  bob -> ecrireXml();

  delete bob;
  delete gars;
  do
    {
      delete war.back();
      war.pop_back();
    }
  while(!war.empty());
  
  return 0;
}
